import { createReducer } from 'reduxsauce'
import { REHYDRATE } from 'redux-persist/es/constants'
import {
  GET_DECISION_FLOWS,
  START_JOUNEY,
  MAKE_CHOICE,
  MOVE_TO_STEP,
  CLEAR_FLOW_NODES,
  GET_SURVEY_TEMPLATES,
  START_SURVEY,
  MOVE_TO_SURVEY_STEP,
  SUBMIT_SURVEY,
  GET_DECISION_RESULT,
  GET_LAST_DECISION,
  SYNC_NUMBER,
  CLEAR_RESULT_ERROR,
  GET_FLOWS_NUMBER,
  GET_DECISION_DETAIL,
  GET_RESULT_DOCTORS,
  GET_RESULT_FEEDITEMS,
  GET_RESULT_GOODS,
  GET_TEMPLATES_BY_TAG_IDS,
} from '@ACTIONS/decision'
import { FLOW_NODE_TYPE } from '@CONSTANTS/decision'

const INITIAL_STATE = {
  initLoadingSurvey: true,
  decisionList: [],
  currentDecision: {},
  loadingDecision: true,
  decisionNodeFlow: [],
  loadingNextNode: false,
  loadingSurveys: true,
  surveyList: [],
  currentSurvey: {},
  surveyTemplate: {},
  surveyNodeCode: 0,
  surveyChoices: [],
  isSurvey: false,
  decisionResult: {},
  loadingLastDecision: false,
  lastDecision: {},
  loadingDecisionResult: true,
  decisionResultError: false,
  decisionNumber: 0,
  decisionDetail: {},
  loadingDecisionDetail: true,
  decisionNodeFlowResult: null,
  resultDoctors: [],
  resultFeedItems: [],
  resultGoods: [],
  templates: [],
}

const initialNode = { Type: FLOW_NODE_TYPE.Loading, p8Id: 'initialNode-loading' }

const rehydrate = (state, { payload }) => {
  if (payload && payload.decision) {
    return { ...INITIAL_STATE, ...payload.decision }
  }
  return { ...state }
}

export default createReducer(INITIAL_STATE, {
  [REHYDRATE]: rehydrate,

  [GET_DECISION_FLOWS.REQUEST]: (state, { isInitial }) => ({
    ...state,
    loadingDecision: isInitial,
  }),
  [GET_DECISION_FLOWS.SUCCESS]: (state, { list, isInitial }) => ({
    ...state,
    decisionList: isInitial ? list : [...state.decisionList, ...list],
    loadingDecision: false,
  }),
  [GET_DECISION_FLOWS.FAILURE]: state => ({
    ...state,
    loadingDecision: false,
  }),

  [GET_SURVEY_TEMPLATES.REQUEST]: (state, { isInitial }) => ({
    ...state,
    loadingSurveys: isInitial,
  }),
  [GET_SURVEY_TEMPLATES.SUCCESS]: (state, { list, isInitial }) => ({
    ...state,
    surveyList: isInitial ? list : [...state.surveyList, ...list],
    loadingSurveys: false,
  }),
  [GET_SURVEY_TEMPLATES.FAILURE]: state => ({
    ...state,
    loadingSurveys: false,
  }),

  [START_JOUNEY.REQUEST]: state => ({
    ...state,
    decisionNodeFlow: [initialNode],
    loadingNextNode: true,
    decisionNodeFlowResult: null,
    initLoadingSurvey: true,
    isSurvey: false,
  }),
  [START_JOUNEY.SUCCESS]: (state, { data }) => {
    const { currentDecision } = state
    return {
      ...state,
      decisionNodeFlow: [data],
      loadingNextNode: false,
      initLoadingSurvey: false,
      currentDecision: {
        ...currentDecision,
        ...data,
        JourneyNumber: (currentDecision.JourneyNumber || 0) + 1,
      },
    }
  },
  [START_JOUNEY.FAILURE]: state => ({
    ...state,
    loadingNextNode: false,
  }),

  [START_SURVEY.REQUEST]: state => ({
    ...state,
    decisionNodeFlow: [initialNode],
    loadingNextNode: true,
    decisionNodeFlowResult: null,
    isSurvey: true,
    initLoadingSurvey: true
  }),
  [START_SURVEY.SUCCESS]: (state, { data = {} }) => {
    const { Template = {} } = data
    const { Questions } = Template
    return {
      ...state,
      decisionNodeFlow: [Questions[0]],
      loadingNextNode: false,
      currentSurvey: data,
      surveyTemplate: Template,
      initLoadingSurvey: false,
    }
  },
  [START_SURVEY.FAILURE]: state => ({
    ...state,
    loadingNextNode: false,
    initLoadingSurvey: false,
  }),

  [MAKE_CHOICE.REQUEST]: (state, { data }) => {
    const { decisionNodeFlow } = state
    const newData = [...decisionNodeFlow]
    const newDataIndex = newData.length - 1
    if (!decisionNodeFlow.length) {
      return state
    }
    newData[newDataIndex].AnswerChoice = data
    return {
      ...state,
      decisionNodeFlow: [...newData, initialNode],
      loadingNextNode: true,
    }
  },
  [MAKE_CHOICE.SUCCESS]: (state, { data }) => {
    const { decisionNodeFlow, decisionNodeFlowResult } = state
    const { Type } = data
    const isResult = Type === FLOW_NODE_TYPE.Leaf
    const newList = decisionNodeFlow.filter(item => item?.Type !== FLOW_NODE_TYPE.Loading)
    return {
      ...state,
      decisionNodeFlow: isResult ? newList : [...newList, data],
      loadingNextNode: false,
      decisionNodeFlowResult: isResult ? data : decisionNodeFlowResult
    }
  },
  [MAKE_CHOICE.FAILURE]: state => ({
    ...state,
    loadingNextNode: false,
  }),

  [MOVE_TO_STEP.REQUEST]: (state, { payload = {} }) => {
    const { Cursor } = payload
    const flow = [...state.decisionNodeFlow]
    const index = (flow.findIndex(item => item.Cursor === Cursor) + 1) || 1
    flow.splice(index)
    return {
      ...state,
      decisionNodeFlow: flow,
    }
  },

  [CLEAR_FLOW_NODES.REQUEST]: state => ({
    ...state,
    decisionNodeFlow: [],
    surveyNodeCode: 0,
    surveyChoices: [],
  }),
  [MOVE_TO_SURVEY_STEP.REQUEST]: state => ({
    ...state,
    loadingNextNode: true,
  }),
  [MOVE_TO_SURVEY_STEP.SUCCESS]: (state, { questionCode, answerChoice }) => {
    const { surveyTemplate, surveyChoices } = state
    const { Questions } = surveyTemplate
    let newQuestions = [...Questions]
    newQuestions[questionCode - 1].AnswerChoice = answerChoice
    newQuestions = newQuestions.map(item => ({
      ...item,
      AnswerChoice: item.Code > questionCode ? null : item.AnswerChoice
    }))
    const newChoicesArr = [...surveyChoices]
    newChoicesArr[questionCode - 1] = {
      Code: questionCode,
      AnswerChoice: answerChoice?.Label,
    }
    return {
      ...state,
      surveyNodeCode: questionCode,
      surveyTemplate: {
        ...surveyTemplate,
        Questions: newQuestions
      },
      surveyChoices: newChoicesArr,
      decisionNodeFlow: newQuestions.slice(0, questionCode + 1),
      loadingNextNode: false,
    }
  },
  [MOVE_TO_SURVEY_STEP.FAILURE]: state => ({
    ...state,
    loadingNextNode: false,
  }),

  [SUBMIT_SURVEY.SUCCESS]: (state, {
    data, questionCode, lastSurveyChoices
  }) => {
    const {
      decisionNodeFlow, surveyTemplate, surveyList, surveyChoices
    } = state
    const { Template } = data
    const { Questions } = surveyTemplate
    const newQuestions = [...Questions]
    newQuestions[questionCode - 1].AnswerChoice = data
    return {
      ...state,
      surveyNodeCode: decisionNodeFlow.length,
      currentSurvey: data,
      loadingNextNode: false,
      decisionNodeFlowResult: data,
      decisionNodeFlow: newQuestions,
      surveyTemplate: {
        ...surveyTemplate,
        Questions: newQuestions
      },
      surveyList: surveyList.map(item => ({ ...item, Taken: Template?.p8Id === item.p8Id ? true : item.Taken })),
      surveyChoices: [...surveyChoices, lastSurveyChoices]
    }
  },
  [SUBMIT_SURVEY.FAILURE]: state => ({
    ...state,
    loadingNextNode: false,
  }),
  [GET_DECISION_RESULT.REQUEST]: state => ({
    ...state,
    decisionResult: {},
    loadingDecisionResult: true,
    decisionResultError: false,
  }),
  [GET_DECISION_RESULT.SUCCESS]: (state, { data }) => ({
    ...state,
    decisionResult: data,
    loadingDecisionResult: false,
    decisionResultError: false
  }),
  [GET_DECISION_RESULT.FAILURE]: (state, { decisionResultError }) => ({
    ...state,
    loadingDecisionResult: false,
    decisionResultError,
  }),

  [GET_LAST_DECISION.REQUEST]: state => ({
    ...state,
    loadingLastDecision: true,
    lastDecision: {},
  }),
  [GET_LAST_DECISION.SUCCESS]: (state, { data }) => ({
    ...state,
    loadingLastDecision: false,
    lastDecision: data,
  }),
  [GET_LAST_DECISION.FAILURE]: state => ({
    ...state,
    loadingLastDecision: false,
  }),

  [SYNC_NUMBER.REQUEST]: (state, { isSurvey, id }) => {
    const {
      surveyList = [], decisionList
    } = state
    if (isSurvey) {
      return {
        ...state,
        surveyList: surveyList.map(item => ({
          ...item,
          ParticipantNumber: item.p8Id === id ? (item.ParticipantNumber || 0) + 1 : item.ParticipantNumber,
        })),
      }
    }
    return {
      ...state,
      decisionList: decisionList.map(item => ({
        ...item,
        JourneyNumber: item.p8Id === id ? (item.JourneyNumber || 0) + 1 : item.JourneyNumber,
      })),
    }
  },
  [CLEAR_RESULT_ERROR.REQUEST]: state => ({
    ...state,
    decisionResultError: false,
    loadingDecisionResult: true,
  }),

  [GET_FLOWS_NUMBER.SUCCESS]: (state, { num }) => ({
    ...state,
    decisionNumber: num,
  }),
  [GET_DECISION_DETAIL.REQUEST]: (state, { isSurvey }) => ({
    ...state,
    decisionDetail: {},
    loadingDecisionDetail: true,
    lastDecision: {},
    isSurvey,
    loadingLastDecision: true
  }),
  [GET_DECISION_DETAIL.SUCCESS]: (state, { data }) => ({
    ...state,
    decisionDetail: data,
    loadingDecisionDetail: false
  }),
  [GET_RESULT_DOCTORS.REQUEST]: state => ({
    ...state,
    resultDoctors: []
  }),
  [GET_RESULT_DOCTORS.SUCCESS]: (state, { data }) => ({
    ...state,
    resultDoctors: data
  }),
  [GET_RESULT_FEEDITEMS.REQUEST]: state => ({
    ...state,
    resultFeedItems: []
  }),
  [GET_RESULT_FEEDITEMS.SUCCESS]: (state, { data }) => ({
    ...state,
    resultFeedItems: data
  }),
  [GET_RESULT_GOODS.REQUEST]: state => ({
    ...state,
    resultGoods: []
  }),
  [GET_RESULT_GOODS.SUCCESS]: (state, { data }) => ({
    ...state,
    resultGoods: data
  }),
  [GET_TEMPLATES_BY_TAG_IDS.SUCCESS]: (state, { templates }) => ({
    ...state,
    templates
  }),
  [GET_TEMPLATES_BY_TAG_IDS.FAILURE]: (state, { error }) => ({
    ...state,
    error
  }),
  [GET_TEMPLATES_BY_TAG_IDS.REQUEST]: state => ({
    ...state,
    templates: []
  }),
})
